Hive SQL单元测试介绍

动机

Hive被广泛应用大数据领域。它经常用于大型数据集的临时查询和用于实现ETL。与即席查询(Ad Hoc )不同,为ETL编写的Hive SQL具有一些不同的属性:

  • 通常按计划重复执行。
  • 它通常是一个庞大而复杂的代码体。
  • 更长的寿命,长期坚持组织的代码库。
  • 经常随着时间的推移对其进行修改
  • 对组织的运作至关重要,因为它可以生成有价值的数据。

展示此类属性的代码是单元测试覆盖的强有力候选者,因为它很容易出现错误,错误和意外破坏,所有这些都可能对组织构成风险。

挑战

Hive和Hive SQL都存在许多挑战,这使得构建基于Hive的ETL系统的单元测试变得困难。这些可以概括地描述如下:

  • 组件边界不清晰
  • 环境
  • 执行速度

模块化

通过模块化使用Hive实现的流程,它们变得更容易有效地测试并且更容易适应变化。尽管Hive提供了许多用于模块化的向量,但并不总是清楚如何分解大型过程。将查询逻辑封装到组件中的功能分为两个垂直问题:列级逻辑和设置级逻辑。列级逻辑是指应用于查询中各列或列组的表达式,通常称为“函数”。设置级别逻辑涉及操纵数据分组的Hive SQL构造,例如:列投影与 SELECTGROUP BY 聚合, JOIN s, ORDER BY 排序等。在任何一种情况下,我们都希望单个组件存在于自己的源文件或可部署artifact中并导入根据构图的需要。对于基于Hive SQL的组件, SOURCE 命令提供此功能。

列级逻辑的封装

在列级逻辑的情况下,Hive提供 UDFsmacros ,允许用户提取和重用应用于列的表达式。一旦定义,UDF和宏可以很容易地隔离进行测试。 UDF可以使用现有的Java / Python单元测试工具(如JUnit)进行简单测试,而宏需要Hive命令行界面来执行宏声明,然后使用一些示例 SELECT 语句来练习它。

设置级逻辑的封装

与列级逻辑不同,如何最好地封装和组合基于集合的逻辑集合是不太明显的。请考虑以下包含联接,分组和列投影的复杂查询示例:

SELECT ... FROM (                  -- Query 1
  SELECT ... FROM (                --  Query 2
    SELECT ... FROM (              --   Query 3
      SELECT ... FROM a WHERE ...  --    Query 4
    ) A LEFT JOIN (                --   Query 3
      SELECT ... FROM b            --    Query 5
    ) B ON (...)                   --   Query 3
  ) ab FULL OUTER JOIN (           --  Query 2
    SELECT ... FROM c WHERE ...    --   Query 6
  ) C ON (...)                     --  Query 2
) abc LEFT JOIN (                  -- Query 1
  SELECT ... FROM d WHERE ...      --  Query 7
) D ON (...)                       -- Query 1
GROUP BY ...;                      -- Query 1

此查询具有无法单独验证。它似乎实际上是由至少7个不同的查询组成的。为了有效地对这个过程进行单元测试,我们必须将每个子查询封装到单独的组件中,以便可以独立测试它们。为实现这一目标,我们可以采取多种方法,包括:

  • 使用中间表顺序执行组件。
  • 视图
  • 查询片段的变量替换。
  • SQL 函数/过程。

有限的测试表明,VIEW比使用具有中间表的组件的顺序执行更有效。中间表解决方案(包括 TEMPORARY 表)运行时间更长,生成更多I / O,并限制查询优化机会。VIEW似乎没有经常预言的性能问题。

变量替换也被建议作为模块化大型查询的方法,但是在检查时发现它不合适,因为需要额外的bash文件会使测试更复杂。还可考虑了HPL/SQL,但它没有查询模块化所需的必要流水线功能。

参考资料

工具和框架

简化测试声明和执行的框架是有帮助的。通常,这些工具允许指定以下许多方法:

  • 执行环境配置:通常为 hiveconfhivevar 参数。
  • 声明输入测试数据:创建或选择支持某些源表的文件。
  • 测试的可执行组件的定义:通常是测试中的SQL脚本。
  • 期望:这些可以是参考数据文件的形式,或者可以使用进一步的查询进行细粒度断言。

精确的细节当然是特定于框架的,但一般而言,工具通过将开发人员提供的工件组合成如下序列来管理测试的整个生命周期:

  • 配置Hive执行环境。
  • 设置测试输入数据。
  • 执行测试中的SQL脚本。
  • 提取执行脚本写入的数据。
  • 对提取的数据进行断言。

目前有许多具体方法可供选择:

  • HiveRunner :使用Java,Hive SQL和JUnit声明测试用例,并且可以在IDE中本地执行。该库侧重于易用性和执行速度。无需安装本地Hive / Hadoop。提供完整的测试隔离,细粒度断言和无缝UDF集成(它们只需要在项目类路径上)。 Metastore由内存数据库支持,以提高测试性能。

  • beetest :使用Hive SQL和“预期”数据文件声明测试用例。使用命令行上的脚本执行测试套件。显然需要在执行测试的环境中安装HDFS。

  • hive_test :使用Java,Hive SQL和JUnit声明测试用例,并且可以在IDE中本地执行。

  • HiveQLUnit: 在您喜欢的IDE中测试您的Hive脚本。使用Spark来执行测试。

  • How to utilise the Hive project's internal test framework

有用的做法

以下Hive特定实践可用于使过程更适合单元测试,并有助于简化单个测试。

  • 将大型或复杂查询模块化为多个较小的组件。这些更容易理解,维护和测试。
  • 使用宏或UDF来封装重复或复杂的列表达式。
  • 使用 Hive variables 将SQL脚本与特定环境分离。例如,使用 LOCATION ${myTableLocation} 优先于 LOCATION /hard/coded/path 可能是明智之举。
  • 缩小测试范围。对表的整个内容进行粗略断言是脆弱的并且具有高维护要求。
  • 使用 SOURCE 命令组合多个较小的SQL脚本。
  • 通过创建简单的测试表并将函数应用于这些表中的列来测试宏和UDF的集成。
  • 通过在标准测试框架(如JUnit)中直接调用生命周期方法( initializeevaluate 等)来测试UDF。

相关问题

  • HIVE-12703 :CLI不可知的HQL导入命令实现

其他Hive单元测试问题

虽然没有与Hive SQL特别相关,但是存在用于测试Hive其他方面的工具生态系统。特别是 BeeJU 项目提供了JUnit规则,以简化与Hive Metastore和HiveServer2服务的集成测试。如果您正在开发旨在利用Hive元数据功能的替代数据处理框架或工具,这些都很有用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容